{{!

  Copyright (c) Meta Platforms, Inc. and affiliates.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

}}
{{#import "common/common" as m_common}}
{{#import "common/typehints" as typehints}}
{{#import "common/types" as m_types}}

{{!
Mangles exception field name in generated response struct, so bad user input
doesn't cause bugs. Example bugs from bad user input:
  a. user calls an exception field "success"
  b. user provides multiple fields with the same name

Whisker partial equivalent to the macro `fields/exception_field_name`, without
a dependency on mstch implicit index property.
}}
{{#let export partial exception_field_name |field index|}}
{{#pragma ignore-newlines}}
_ex{{index}}__{{field.py_name}}
{{/let partial}}

{{#let partial aliased_pep484_type |type| captures |m_common m_types typehints|}}
{{#pragma ignore-newlines}}
  {{#if type.has_adapter?}}
    {{#let adapter = type.adapter}}
{{adapter.type_hint}}{{#if adapter.is_generic?}}[{{#partial typehints.unadapted_type type=type}}]{{/if}}
  {{#else if type.structured?}}
    {{#let structured = type.true_type}}
{{#if structured.need_module_path?}}{{structured.module_mangle}}.{{/if}}{{#partial m_common.private_alias_prefix}}{{structured.py_name}}
  {{#else if type.list?}}
{{#partial m_types.sequence}}[{{#partial aliased_pep484_type type=type.true_type.elem_type}}]
  {{#else if type.set?}}
{{#partial m_types.set}}[{{#partial aliased_pep484_type type=type.true_type.elem_type}}]
  {{#else if type.map?}}
    {{#let map = type.true_type}}
{{#partial m_types.mapping}}[{{#partial typehints.pep484_type type=map.key_type}}, {{#partial aliased_pep484_type type=map.val_type}}]
  {{#else if type.void?}}
None
  {{#else if type.enum?}}
    {{#let enum = type.true_type}}
{{#if enum.need_module_path?}}{{enum.module_mangle}}.{{/if}}{{#partial m_common.private_alias_prefix}}{{enum.name}}
  {{#else}}
{{#partial typehints.unadapted_builtin type=type}}
  {{/if type.has_adapter?}}
{{/let partial}}


{{! Adapted type if field has adapter, otherwise the original type }}
{{#let export partial aliased_or_adapted_type_pyi |type adapter| captures |aliased_pep484_type|}}
  {{#pragma ignore-newlines}}
  {{#if (object.notnull? adapter)}}
{{adapter.type_hint}}{{#if adapter.is_generic?}}[{{#partial aliased_pep484_type type=type}}]{{/if}}
  {{#else}}
{{#partial aliased_pep484_type type=type}}
  {{/if (object.notnull? adapter)}}
{{/let partial}}

{{! Adapted type hint if field has adapter, otherwise the original type }}
{{#let export partial adapted_type_pyi |type adapter| captures |typehints|}}
  {{#pragma ignore-newlines}}
  {{#if (object.notnull? adapter)}}
{{adapter.type_hint}}{{#if adapter.is_generic?}}[{{#partial typehints.pep484_type type=type}}]{{/if}}
  {{#else}}
{{#partial typehints.pep484_type type=type}}
  {{/if (object.notnull? adapter)}}
{{/let partial}}

{{! Generate the type hints for fields }}
{{#let export partial field_type_pyi |field| captures |adapted_type_pyi|}}
  {{#pragma ignore-newlines}}
{{#if field.optional?}}_typing.Optional[{{/if}}
{{#partial adapted_type_pyi type=field.type adapter=field.adapter}}
{{#if field.optional?}}]{{/if}}
{{/let partial}}

{{#let export partial iter_return_type |fields| captures |adapted_type_pyi|}}
{{! `__iter__()` return type }}
{{#pragma ignore-newlines}}
_typing.Iterator[_typing.Tuple[builtins.str, _typing.Union[
  {{#each (array.enumerate fields with_first=true) as |i field first?|}}
{{#if (not first?)}}, {{/if}}{{#partial adapted_type_pyi type=field.type adapter=field.adapter}}
    {{#else}}
None
  {{/each}}
]]]
{{/let partial}}
